package io.itit.ecp.admin.provide.action.controller;


import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.itit.ecp.admin.common.enums.IMeterDeviceEnums;
import io.itit.ecp.admin.common.enums.MeterDeviceStaticsTypeEnums;
import io.itit.ecp.admin.provide.action.resp.ISceneInfoResp;
import io.itit.ecp.admin.provide.helper.SceneHelper;
import io.itit.ecp.admin.server.entity.EnergyConsumptionTypeEntity;
import io.itit.ecp.admin.server.entity.EnergyDataEntity;
import io.itit.ecp.admin.server.entity.SceneCompanyEntity;
import io.itit.ecp.admin.server.service.IEnergyConsumptionTypeService;
import io.itit.ecp.admin.server.service.IEnergyDataService;
import io.itit.ecp.admin.server.service.ISceneCompanyService;
import io.itit.grass.common.provide.action.resp.ResultResp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户用能优化建议
 */
@Api(tags = "用户用能优化建议")
@RestController
@RequestMapping("/ecp-admin/runtimeOptimizationReport/")
public class UserEnergyOptimizationSuggestionsController {

    @Resource
    private IEnergyConsumptionTypeService energyConsumptionTypeService;

    @Resource
    private IEnergyDataService energyDataService;

    @Resource
    private ISceneCompanyService sceneCompanyService;

    /**
     * 用能分析-能耗说明
     *
     * @param sceneProjectId sceneProjectId
     * @param sceneEdificeId sceneEdificeId
     * @param sceneFloorId   sceneFloorId
     * @param sceneRoomId    sceneRoomId
     * @param statisticsMode statisticsMode
     * @param startDate      startDate
     * @param endDate        endDate
     */
    @ApiOperation("用能分析-能耗说明")
    @GetMapping("energyConsumptionDescription")
    public ResultResp<Map<String, Object>> energyConsumptionDescription(@RequestParam(required = false) String sceneProjectId,
                                                                        @RequestParam(required = false) String sceneEdificeId,
                                                                        @RequestParam(required = false) String sceneFloorId,
                                                                        @RequestParam(required = false) String sceneRoomId,
                                                                        @RequestParam(required = false) String statisticsMode,
                                                                        @RequestParam(required = false) String startDate,
                                                                        @RequestParam(required = false) String endDate) {
        LocalDateTime start = null;
        LocalDateTime end = LocalDateTime.now();
        if (StringUtils.hasLength(statisticsMode)) {
            start = CarbonEmissionReportController.getStartDate(statisticsMode, startDate);
            end = CarbonEmissionReportController.getEndDate(statisticsMode, endDate);
        }
        List<EnergyConsumptionTypeEntity> typeEntityList = energyConsumptionTypeService.list(new LambdaQueryWrapper<EnergyConsumptionTypeEntity>()
                .eq(EnergyConsumptionTypeEntity::getStatus, "1")
                .orderByAsc(EnergyConsumptionTypeEntity::getCreateTm));

        List<EnergyDataEntity> energyDataEntities = energyDataService.list(new LambdaQueryWrapper<EnergyDataEntity>()
                .select(EnergyDataEntity::getSceneCompanyId, EnergyDataEntity::getSceneProjectId,
                        EnergyDataEntity::getSceneEdificeId, EnergyDataEntity::getSceneFloorId, EnergyDataEntity::getSceneRoomId,
                        EnergyDataEntity::getEnergyTypeId, EnergyDataEntity::getSolidifyDate, EnergyDataEntity::getStandardCoal)
                .eq(StringUtils.hasLength(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.hasLength(sceneEdificeId), EnergyDataEntity::getSceneEdificeId, sceneEdificeId)
                .eq(StringUtils.hasLength(sceneFloorId), EnergyDataEntity::getSceneFloorId, sceneFloorId)
                .eq(StringUtils.hasLength(sceneRoomId), EnergyDataEntity::getSceneRoomId, sceneRoomId)
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .isNotNull(EnergyDataEntity::getStandardCoal)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .orderByAsc(EnergyDataEntity::getSolidifyDate)
        );
        Map<String, Object> result = new HashMap<>();
        result.put("startDate", Objects.isNull(start) ? null : start.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        result.put("endDate", end.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        List<Map<String, Object>> dataList = new ArrayList<>(typeEntityList.size());
        for (EnergyConsumptionTypeEntity consumptionType : typeEntityList) {
            Map<String, Object> map = new HashMap<>(2);
            map.put("name", consumptionType.getEnergyName());
            BigDecimal value = energyDataEntities.stream()
                    .filter(energyDataEntity -> StringUtils.pathEquals(consumptionType.getId(), energyDataEntity.getEnergyTypeId()))
                    .map(EnergyDataEntity::getStandardCoal)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            map.put("value", value);
            dataList.add(map);
        }
        result.put("dataList", dataList);
        result.put("solidifyDateList", groupBySolidifyDate(energyDataEntities, typeEntityList)); // 根据数据时间维度的列表数据
        result.put("sceneInfoDataList", groupBySceneInfo(energyDataEntities, typeEntityList)); // 根据项目，场景维度的列表数据
        result.put("companyDataList", groupByCompanyId(energyDataEntities, sceneProjectId)); // 根据公司维度的列表数据
        result.put("peakValleySituationList", Collections.emptyList()); //TODO: 峰谷情况,数据来源：AI算法团队提供
        return ResultResp.success(result);
    }

    @Data
    @Accessors(chain = true)
    private static class SceneInfoData implements ISceneInfoResp {

        private String sceneProjectId;

        private String sceneEdificeId;

        private String sceneFloorId;

        private String sceneRoomId;

        private String sceneInfoName;

        private BigDecimal[] values;

        private BigDecimal total;

        public void setSceneInfoName(String sceneInfoName) {
            this.sceneInfoName = sceneInfoName;
        }
    }

    private List<SceneInfoData> groupBySceneInfo(List<EnergyDataEntity> energyDataEntities, List<EnergyConsumptionTypeEntity> typeEntityList) {
        List<SceneInfoData> resultList = new ArrayList<>();
        Map<String, List<EnergyDataEntity>> energyDataMap = energyDataEntities.stream()
                .collect(Collectors.groupingBy(item -> item.getSceneEdificeId() +
                                (StringUtils.hasLength(item.getSceneFloorId()) ? item.getSceneFloorId() : "") +
                                (StringUtils.hasLength(item.getSceneRoomId()) ? item.getSceneRoomId() : "")
                        )
                );
        for (Map.Entry<String, List<EnergyDataEntity>> entry : energyDataMap.entrySet()) {
            List<EnergyDataEntity> value = entry.getValue();
            SceneInfoData data = new SceneInfoData()
                    .setSceneProjectId(value.get(0).getSceneProjectId())
                    .setSceneEdificeId(value.get(0).getSceneEdificeId())
                    .setSceneFloorId(value.get(0).getSceneFloorId())
                    .setSceneRoomId(value.get(0).getSceneRoomId())
                    .setTotal(value.stream().map(EnergyDataEntity::getStandardCoal).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
            BigDecimal[] values = new BigDecimal[typeEntityList.size()];
            int index = 0;
            for (EnergyConsumptionTypeEntity consumptionType : typeEntityList) {
                BigDecimal val = value.stream().filter(item -> StringUtils.pathEquals(item.getEnergyTypeId(), consumptionType.getId()))
                        .map(EnergyDataEntity::getStandardCoal).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                values[index] = (values[index] == null ? BigDecimal.ZERO : values[index]).add(val);
                index++;
            }
            data.setValues(values);
            resultList.add(data);
        }
        return SceneHelper.i().setSceneInfo(resultList);
    }

    private List<Map<String, Object>> groupByCompanyId(List<EnergyDataEntity> energyDataEntities, String sceneProjectId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<SceneCompanyEntity> companyEntities = sceneCompanyService.list(new LambdaQueryWrapper<SceneCompanyEntity>()
                .eq(StringUtils.hasLength(sceneProjectId), SceneCompanyEntity::getSceneProjectId, sceneProjectId)
                .orderByAsc(SceneCompanyEntity::getCompanyName));
        for (SceneCompanyEntity companyEntity : companyEntities) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", companyEntity.getId());
            map.put("companyName", companyEntity.getCompanyName());
            map.put("value", energyDataEntities.stream()
                    .filter(item -> StringUtils.pathEquals(companyEntity.getSceneProjectId(), item.getSceneProjectId()))
                    .map(EnergyDataEntity::getStandardCoal)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
            );
            resultList.add(map);
        }
        return resultList;
    }

    private List<Map<String, Object>> groupBySolidifyDate(List<EnergyDataEntity> energyDataEntities, List<EnergyConsumptionTypeEntity> typeEntityList) {
        List<Map<String, Object>> solidifyDateList = new ArrayList<>();
        TreeMap<String, List<EnergyDataEntity>> solidifyDateMap = energyDataEntities.stream()
                .collect(Collectors.groupingBy(item -> DateUtil.format(item.getSolidifyDate(), "yyyy-MM-dd"), TreeMap::new, Collectors.toList()));
        for (Map.Entry<String, List<EnergyDataEntity>> entry : solidifyDateMap.entrySet()) {
            Map<String, Object> map = new HashMap<>();
            map.put("solidifyDate", entry.getKey());
            List<EnergyDataEntity> value = entry.getValue();
            List<BigDecimal> values = new ArrayList<>();
            for (EnergyConsumptionTypeEntity consumptionType : typeEntityList) {
                BigDecimal standardCoal = value.stream()
                        .filter(item -> StringUtils.pathEquals(consumptionType.getId(), item.getEnergyTypeId()))
                        .map(EnergyDataEntity::getStandardCoal)
                        .filter(Objects::nonNull)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                values.add(standardCoal);
            }
            map.put("values", values);
            map.put("total", values.stream().reduce(BigDecimal.ZERO, BigDecimal::add));
            solidifyDateList.add(map);
        }
        return solidifyDateList;
    }

    /**
     * 光伏发电情况分析
     *
     * @param sceneProjectId    sceneProjectId
     * @param sceneEdificeId    sceneEdificeId
     * @param sceneFloorId      sceneFloorId
     * @param sceneRoomId       sceneRoomId
     * @param statisticsMode    statisticsMode
     * @param solidifyDateStart solidifyDateStart
     * @param solidifyDateEnd   solidifyDateEnd
     */
    @ApiOperation("光伏发电情况分析")
    @GetMapping("photovoltaicPowerAnalysis")
    public ResultResp<Map<String, Object>> photovoltaicPowerAnalysis(String sceneProjectId,
                                                                     String sceneEdificeId,
                                                                     String sceneFloorId,
                                                                     String sceneRoomId,
                                                                     String statisticsMode,
                                                                     String solidifyDateStart, String solidifyDateEnd) {
        LocalDateTime start = null;
        LocalDateTime end = LocalDateTime.now();
        if (StringUtils.hasLength(statisticsMode)) {
            start = CarbonEmissionReportController.getStartDate(statisticsMode, solidifyDateStart);
            end = CarbonEmissionReportController.getEndDate(statisticsMode, solidifyDateEnd);
        }
        // 光伏发电量
        List<EnergyDataEntity> energyDataEntities = energyDataService.list(new LambdaQueryWrapper<EnergyDataEntity>()
                .select(EnergyDataEntity::getSolidifyDate, EnergyDataEntity::getMeterValue)
                .eq(StringUtils.hasLength(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.hasLength(sceneEdificeId), EnergyDataEntity::getSceneEdificeId, sceneEdificeId)
                .eq(StringUtils.hasLength(sceneFloorId), EnergyDataEntity::getSceneFloorId, sceneFloorId)
                .eq(StringUtils.hasLength(sceneRoomId), EnergyDataEntity::getSceneRoomId, sceneRoomId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType)
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.POWER_GENERATION.getValue())
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .isNotNull(EnergyDataEntity::getMeterValue)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .orderByAsc(EnergyDataEntity::getSolidifyDate)
        );
        Map<String, List<EnergyDataEntity>> solidifyDate1Map = energyDataEntities.stream()
                .collect(Collectors.groupingBy(item -> DateUtil.format(item.getSolidifyDate(), "yyyy-MM-dd"), TreeMap::new, Collectors.toList()));

        // 上网电量数据
        energyDataEntities = energyDataService.list(new LambdaQueryWrapper<EnergyDataEntity>()
                .select(EnergyDataEntity::getSolidifyDate, EnergyDataEntity::getMeterValue)
                .eq(StringUtils.hasLength(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.hasLength(sceneEdificeId), EnergyDataEntity::getSceneEdificeId, sceneEdificeId)
                .eq(StringUtils.hasLength(sceneFloorId), EnergyDataEntity::getSceneFloorId, sceneFloorId)
                .eq(StringUtils.hasLength(sceneRoomId), EnergyDataEntity::getSceneRoomId, sceneRoomId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType13.readMeterType)
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.ON_GRID_ENERGY.getValue())
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .isNotNull(EnergyDataEntity::getMeterValue)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .orderByAsc(EnergyDataEntity::getSolidifyDate)
        );
        Map<String, List<EnergyDataEntity>> solidifyDate2Map = energyDataEntities.stream()
                .collect(Collectors.groupingBy(item -> DateUtil.format(item.getSolidifyDate(), "yyyy-MM-dd"), TreeMap::new, Collectors.toList()));
        Set<String> dateSet = new TreeSet<>();
        dateSet.addAll(solidifyDate1Map.keySet());
        dateSet.addAll(solidifyDate2Map.keySet());
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("dateList", dateSet);
        BigDecimal[] values1 = new BigDecimal[dateSet.size()];
        BigDecimal[] values2 = new BigDecimal[dateSet.size()];
        BigDecimal[] values3 = new BigDecimal[dateSet.size()];// 自用量
        BigDecimal[] values4 = new BigDecimal[dateSet.size()];// 消纳率
        int index = 0;
        for (String date : dateSet) {
            List<EnergyDataEntity> dataEntities = solidifyDate1Map.getOrDefault(date, Collections.emptyList());
            BigDecimal value = dataEntities.stream().map(EnergyDataEntity::getMeterValue).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
            values1[index] = value;

            dataEntities = solidifyDate2Map.getOrDefault(date, Collections.emptyList());
            value = dataEntities.stream().map(EnergyDataEntity::getMeterValue).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
            values2[index] = value;
            values3[index] = values1[index].subtract(values2[index]);
            values4[index] = values1[index].doubleValue() != 0.0D ? values3[index].divide(values1[index], RoundingMode.HALF_DOWN).multiply(new BigDecimal("100")) : BigDecimal.ZERO;
            index++;
        }
        resultData.put("startDate", Objects.isNull(start) ? null : start.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        resultData.put("endDate", end.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        resultData.put("values1", values1);
        resultData.put("values2", values2);
        resultData.put("values3", values3);
        resultData.put("values4", values4);
        return ResultResp.success(resultData);
    }


    /**
     * 储能情况分析
     *
     * @param sceneProjectId    sceneProjectId
     * @param sceneEdificeId    sceneEdificeId
     * @param sceneFloorId      sceneFloorId
     * @param sceneRoomId       sceneRoomId
     * @param statisticsMode    statisticsMode
     * @param solidifyDateStart solidifyDateStart
     * @param solidifyDateEnd   solidifyDateEnd
     */
    @ApiOperation("储能情况分析")
    @GetMapping("energyStorageAnalysis")
    public ResultResp<Map<String, Object>> energyStorageAnalysis(String sceneProjectId,
                                                                 String sceneEdificeId,
                                                                 String sceneFloorId,
                                                                 String sceneRoomId,
                                                                 String statisticsMode,
                                                                 String solidifyDateStart, String solidifyDateEnd) {
        LocalDateTime start = null;
        LocalDateTime end = LocalDateTime.now();
        if (StringUtils.hasLength(statisticsMode)) {
            start = CarbonEmissionReportController.getStartDate(statisticsMode, solidifyDateStart);
            end = CarbonEmissionReportController.getEndDate(statisticsMode, solidifyDateEnd);
        }
        // 储能充电量
        List<EnergyDataEntity> energyDataEntities = energyDataService.list(new LambdaQueryWrapper<EnergyDataEntity>()
                .select(EnergyDataEntity::getSolidifyDate, EnergyDataEntity::getMeterValue)
                .eq(StringUtils.hasLength(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.hasLength(sceneEdificeId), EnergyDataEntity::getSceneEdificeId, sceneEdificeId)
                .eq(StringUtils.hasLength(sceneFloorId), EnergyDataEntity::getSceneFloorId, sceneFloorId)
                .eq(StringUtils.hasLength(sceneRoomId), EnergyDataEntity::getSceneRoomId, sceneRoomId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType)
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_CHARGING.getValue())
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .isNotNull(EnergyDataEntity::getMeterValue)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .orderByAsc(EnergyDataEntity::getSolidifyDate)
        );
        Map<String, List<EnergyDataEntity>> solidifyDate1Map = energyDataEntities.stream()
                .collect(Collectors.groupingBy(item -> DateUtil.format(item.getSolidifyDate(), "yyyy-MM-dd"), TreeMap::new, Collectors.toList()));

        // 储能放电量
        energyDataEntities = energyDataService.list(new LambdaQueryWrapper<EnergyDataEntity>()
                .select(EnergyDataEntity::getSolidifyDate, EnergyDataEntity::getMeterValue)
                .eq(StringUtils.hasLength(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.hasLength(sceneEdificeId), EnergyDataEntity::getSceneEdificeId, sceneEdificeId)
                .eq(StringUtils.hasLength(sceneFloorId), EnergyDataEntity::getSceneFloorId, sceneFloorId)
                .eq(StringUtils.hasLength(sceneRoomId), EnergyDataEntity::getSceneRoomId, sceneRoomId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType)
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_DISCHARGE.getValue())
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .isNotNull(EnergyDataEntity::getMeterValue)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .orderByAsc(EnergyDataEntity::getSolidifyDate)
        );
        Map<String, List<EnergyDataEntity>> solidifyDate2Map = energyDataEntities.stream()
                .collect(Collectors.groupingBy(item -> DateUtil.format(item.getSolidifyDate(), "yyyy-MM-dd"), TreeMap::new, Collectors.toList()));
        Set<String> dateSet = new TreeSet<>();
        dateSet.addAll(solidifyDate1Map.keySet());
        dateSet.addAll(solidifyDate2Map.keySet());
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("dateList", dateSet);
        BigDecimal[] values1 = new BigDecimal[dateSet.size()];// 储能充电量
        BigDecimal[] values2 = new BigDecimal[dateSet.size()];// 储能放电量
        BigDecimal[] values3 = new BigDecimal[dateSet.size()];// 充电次数
        BigDecimal[] values4 = new BigDecimal[dateSet.size()];// 放电次数
        BigDecimal[] values5 = new BigDecimal[dateSet.size()];// 储能利用率
        int index = 0;
        for (String date : dateSet) {
            List<EnergyDataEntity> dataEntities = solidifyDate1Map.getOrDefault(date, Collections.emptyList());
            BigDecimal value = dataEntities.stream().map(EnergyDataEntity::getMeterValue).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
            values1[index] = value;

            dataEntities = solidifyDate2Map.getOrDefault(date, Collections.emptyList());
            value = dataEntities.stream().map(EnergyDataEntity::getMeterValue).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
            values2[index] = value;
            values3[index] = BigDecimal.ZERO;
            values4[index] = BigDecimal.ZERO;
            values5[index] = values1[index].doubleValue() == 0.0D ? BigDecimal.ZERO : values2[index].divide(values1[index], RoundingMode.HALF_DOWN).multiply(new BigDecimal("100"));
        }
        resultData.put("startDate", Objects.isNull(start) ? null : start.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        resultData.put("endDate", end.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        resultData.put("values1", values1);
        resultData.put("values2", values2);
        resultData.put("values3", values3);
        resultData.put("values4", values4);
        resultData.put("values5", values5);
        return ResultResp.success(resultData);
    }


    /**
     * 充电桩情况分析
     *
     * @param sceneProjectId    sceneProjectId
     * @param sceneEdificeId    sceneEdificeId
     * @param sceneFloorId      sceneFloorId
     * @param sceneRoomId       sceneRoomId
     * @param statisticsMode    statisticsMode
     * @param solidifyDateStart solidifyDateStart
     * @param solidifyDateEnd   solidifyDateEnd
     */
    @ApiOperation("充电桩情况分析")
    @GetMapping("chargingStationAnalysis")
    public ResultResp<Map<String, Object>> chargingStationAnalysis(String sceneProjectId,
                                                                   String sceneEdificeId,
                                                                   String sceneFloorId,
                                                                   String sceneRoomId,
                                                                   String statisticsMode,
                                                                   String solidifyDateStart, String solidifyDateEnd) {
        LocalDateTime start = null;
        LocalDateTime end = LocalDateTime.now();
        if (StringUtils.hasLength(statisticsMode)) {
            start = CarbonEmissionReportController.getStartDate(statisticsMode, solidifyDateStart);
            end = CarbonEmissionReportController.getEndDate(statisticsMode, solidifyDateEnd);
        }
        // 充电桩充电量
        List<EnergyDataEntity> energyDataEntities = energyDataService.list(new LambdaQueryWrapper<EnergyDataEntity>()
                .select(EnergyDataEntity::getSolidifyDate, EnergyDataEntity::getMeterValue)
                .eq(StringUtils.hasLength(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.hasLength(sceneEdificeId), EnergyDataEntity::getSceneEdificeId, sceneEdificeId)
                .eq(StringUtils.hasLength(sceneFloorId), EnergyDataEntity::getSceneFloorId, sceneFloorId)
                .eq(StringUtils.hasLength(sceneRoomId), EnergyDataEntity::getSceneRoomId, sceneRoomId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType)
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_CHARGING.getValue())
                .isNotNull(EnergyDataEntity::getMeterValue)
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .orderByAsc(EnergyDataEntity::getSolidifyDate)
        );
        Map<String, List<EnergyDataEntity>> solidifyDate1Map = energyDataEntities.stream()
                .collect(Collectors.groupingBy(item -> DateUtil.format(item.getSolidifyDate(), "yyyy-MM-dd"), TreeMap::new, Collectors.toList()));

        // 充电桩放电量
        energyDataEntities = energyDataService.list(new LambdaQueryWrapper<EnergyDataEntity>()
                .select(EnergyDataEntity::getSolidifyDate, EnergyDataEntity::getMeterValue)
                .eq(StringUtils.hasLength(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.hasLength(sceneEdificeId), EnergyDataEntity::getSceneEdificeId, sceneEdificeId)
                .eq(StringUtils.hasLength(sceneFloorId), EnergyDataEntity::getSceneFloorId, sceneFloorId)
                .eq(StringUtils.hasLength(sceneRoomId), EnergyDataEntity::getSceneRoomId, sceneRoomId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType)
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_DISCHARGE.getValue())
                .isNotNull(EnergyDataEntity::getMeterValue)
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .orderByAsc(EnergyDataEntity::getSolidifyDate)
        );
        Map<String, List<EnergyDataEntity>> solidifyDate2Map = energyDataEntities.stream()
                .collect(Collectors.groupingBy(item -> DateUtil.format(item.getSolidifyDate(), "yyyy-MM-dd"), TreeMap::new, Collectors.toList()));
        Set<String> dateSet = new TreeSet<>();
        dateSet.addAll(solidifyDate1Map.keySet());
        dateSet.addAll(solidifyDate2Map.keySet());
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("dateList", dateSet);
        BigDecimal[] values1 = new BigDecimal[dateSet.size()];// 充电桩充电量
        BigDecimal[] values2 = new BigDecimal[dateSet.size()];// 充电桩放电量
        BigDecimal[] values3 = new BigDecimal[dateSet.size()];// 充电次数
        BigDecimal[] values4 = new BigDecimal[dateSet.size()];// 放电次数
        BigDecimal[] values5 = new BigDecimal[dateSet.size()];// 充电桩利用率
        int index = 0;
        for (String date : dateSet) {
            List<EnergyDataEntity> dataEntities = solidifyDate1Map.getOrDefault(date, Collections.emptyList());
            BigDecimal value = dataEntities.stream().map(EnergyDataEntity::getMeterValue).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
            values1[index] = value;

            dataEntities = solidifyDate2Map.getOrDefault(date, Collections.emptyList());
            value = dataEntities.stream().map(EnergyDataEntity::getMeterValue).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
            values2[index] = value;
            values3[index] = BigDecimal.ZERO; //TODO:
            values4[index] = BigDecimal.ZERO;//TODO:
            values5[index] = values1[index].doubleValue() == 0.0D ? BigDecimal.ZERO : values2[index].divide(values1[index], RoundingMode.HALF_DOWN).multiply(new BigDecimal("100"));
        }
        resultData.put("startDate", Objects.isNull(start) ? null : start.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        resultData.put("endDate", end.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        resultData.put("values1", values1);
        resultData.put("values2", values2);
        resultData.put("values3", values3);
        resultData.put("values4", values4);
        resultData.put("values5", values5);
        return ResultResp.success(resultData);
    }

}
